package com.cyys.modules.core.utils;

import com.cyys.common.utils.StringUtil;
import com.cyys.modules.generator.model.GeneratorConfigure;
import com.cyys.modules.generator.model.GeneratorTable;
import freemarker.template.Template;
import freemarker.template.TemplateException;

import java.io.*;
import java.util.regex.Matcher;

/**
 * Author GreedyStar
 * Date   2018/4/19
 */
public class FileUtil {

    /**
     * @param templateType 1：通用模板 2：树型模板
     * @param fileType     使用文件类型
     * @param data     填充数据
     * @param configure 包名,工程名
     * @param table 模块名称moudleName,文件夹名称fileDirName,小写类名className
     * @throws IOException
     * @throws TemplateException
     */
    public static void generateToJava(String templateType, int fileType, Object data, GeneratorConfigure configure,
                                      GeneratorTable table) throws IOException, TemplateException {
        String path = getFilePath(fileType, configure.getPackageName(),configure.getProjectName(), table.getMoudleName(), table.getFileDirName(),table.getShiro()) +
                getFileName(fileType, table.getClassName()); // 待生成的代码文件路径
        // 已存在的文件不予覆盖
        File file = new File(path);
        if (file.exists()) {
            file.delete();
//            path += ".generated";
//            System.err.printf("%s already exit. Generating %s \n", fileName, path);
        } else {
            System.out.printf("Generating %s \n", path);
        }
        // 代码生成路径目录不存在则自动创建
        if (!file.getParentFile().exists()) {
            file.getParentFile().mkdirs();
        }
        Template tpl = getTemplate(templateType, fileType); // 获取模板文件
        // 填充数据
        StringWriter writer = new StringWriter();
        tpl.process(data, writer);
        writer.flush();
        // 写入文件
        FileOutputStream fos = new FileOutputStream(path);
        OutputStreamWriter osw = new OutputStreamWriter(fos, "UTF-8");
        BufferedWriter bw = new BufferedWriter(osw, 1024);
        tpl.process(data, bw);
        writer.close();
        bw.close();
    }

    /**
     * 获取模板
     * @param  templateType 1：通用模板 2：树型模板
     * @param fileType 使用文件类型
     * @return
     * @throws IOException
     */
    private static Template getTemplate(String templateType, int fileType) throws IOException {
        if(templateType.equals("1")) {
            switch (fileType) {
                case FreemarketConfigUtil.TYPE_MODEL:
                    return FreemarketConfigUtil.getGeneralInstance().getTemplate("model.java.ftl");
                case FreemarketConfigUtil.TYPE_DAO:
                    return FreemarketConfigUtil.getGeneralInstance().getTemplate("dao.java.ftl");
                case FreemarketConfigUtil.TYPE_SERVICE:
                    return FreemarketConfigUtil.getGeneralInstance().getTemplate("service.java.ftl");
                case FreemarketConfigUtil.TYPE_ACTION:
                    return FreemarketConfigUtil.getGeneralInstance().getTemplate("action.java.ftl");
                case FreemarketConfigUtil.TYPE_MAPPER:
                    return FreemarketConfigUtil.getGeneralInstance().getTemplate("mapper.xml.ftl");
                case FreemarketConfigUtil.PAGE_LIST:
                    return FreemarketConfigUtil.getGeneralInstance().getTemplate("page_list.jsp.ftl");
                case FreemarketConfigUtil.PAGE_INPUT:
                    return FreemarketConfigUtil.getGeneralInstance().getTemplate("page_input.jsp.ftl");
                case FreemarketConfigUtil.PAGE_SELECT:
                    return FreemarketConfigUtil.getGeneralInstance().getTemplate("page_select.jsp.ftl");
                default:
                    return null;
            }
        }else{
            switch (fileType) {
                case FreemarketConfigUtil.TYPE_MODEL:
                    return FreemarketConfigUtil.getTreeInstance().getTemplate("model.java.ftl");
                case FreemarketConfigUtil.TYPE_DAO:
                    return FreemarketConfigUtil.getTreeInstance().getTemplate("dao.java.ftl");
                case FreemarketConfigUtil.TYPE_SERVICE:
                    return FreemarketConfigUtil.getTreeInstance().getTemplate("service.java.ftl");
                case FreemarketConfigUtil.TYPE_ACTION:
                    return FreemarketConfigUtil.getTreeInstance().getTemplate("action.java.ftl");
                case FreemarketConfigUtil.TYPE_MAPPER:
                    return FreemarketConfigUtil.getTreeInstance().getTemplate("mapper.xml.ftl");
                case FreemarketConfigUtil.PAGE_LIST:
                    return FreemarketConfigUtil.getTreeInstance().getTemplate("page_list.jsp.ftl");
                case FreemarketConfigUtil.PAGE_INPUT:
                    return FreemarketConfigUtil.getTreeInstance().getTemplate("page_input.jsp.ftl");
                case FreemarketConfigUtil.PAGE_SELECT:
                    return FreemarketConfigUtil.getTreeInstance().getTemplate("page_select.jsp.ftl");
                default:
                    return null;
            }
        }
    }

    /**
     * 获取文件路径
     *
     * @param fileType 模板类型
     * @return
     * @throws IOException
     */
    private static String getFilePath(int fileType,String packageName,String projectName, String moudleName,String fileDirName,String shiroName) throws IOException {
//        moudleName = moudleName.replaceAll(".",File.separator);
        fileDirName = fileDirName.replaceAll("\\.", Matcher.quoteReplacement(File.separator));
        switch (fileType) {
            case FreemarketConfigUtil.TYPE_MAPPER:
                String xmlPath = FileUtil.getResourcePath() +
                        "mappings" + File.separator +
                        moudleName + File.separator +
                        fileDirName + File.separator;
                xmlPath = xmlPath.replace(projectName,"cyys-core");
                return xmlPath;
            case FreemarketConfigUtil.TYPE_MODEL:
                String modulePath = FileUtil.getSourcePath() +
                        StringUtil.package2Path(packageName) + File.separator +
                        moudleName + File.separator +
                        "model" + File.separator +
                        fileDirName + File.separator;
                modulePath = modulePath.replace(projectName,"cyys-core");
                return modulePath;
            case FreemarketConfigUtil.TYPE_DAO:
                String daoPath = FileUtil.getSourcePath() +
                        StringUtil.package2Path(packageName) + File.separator +
                        moudleName + File.separator +
                        "dao" + File.separator +
                        fileDirName + File.separator;
                daoPath = daoPath.replace(projectName,"cyys-core");
                return daoPath;
            case FreemarketConfigUtil.TYPE_SERVICE:
                String servicePath = FileUtil.getSourcePath() +
                        StringUtil.package2Path(packageName) + File.separator +
                        moudleName + File.separator +
                        "service" + File.separator +
                        fileDirName + File.separator;
                servicePath = servicePath.replace(projectName,"cyys-core");
                return servicePath;
            case FreemarketConfigUtil.TYPE_ACTION:
                String actionPath = FileUtil.getSourcePath() +
                        StringUtil.package2Path(packageName) + File.separator +
                        moudleName + File.separator +
                        "controller" + File.separator +
                        fileDirName + File.separator;
                return actionPath;
            case FreemarketConfigUtil.PAGE_LIST:
                String listPagePath = "";
                if (StringUtil.isNotBlank(shiroName)){
                    listPagePath = FileUtil.getPagePath() +
                            "WEB-INF" + File.separator +
                            "jsp" + File.separator +
                            "module" + File.separator +
                            moudleName + File.separator +
                            fileDirName + File.separator +
                            shiroName + File.separator;
                }else{
                    listPagePath = FileUtil.getPagePath() +
                            "WEB-INF" + File.separator +
                            "jsp" + File.separator +
                            "module" + File.separator +
                            moudleName + File.separator +
                            fileDirName + File.separator +
                            shiroName + File.separator;
                }
                return listPagePath;
            case FreemarketConfigUtil.PAGE_INPUT:
                String inputPagePath = "";
                if (StringUtil.isNotBlank(shiroName)){
                    inputPagePath = FileUtil.getPagePath() +
                            "WEB-INF" + File.separator +
                            "jsp" + File.separator +
                            "module" + File.separator +
                            moudleName + File.separator +
                            fileDirName + File.separator +
                            shiroName + File.separator;
                }else{
                    inputPagePath = FileUtil.getPagePath() +
                            "WEB-INF" + File.separator +
                            "jsp" + File.separator +
                            "module" + File.separator +
                            moudleName + File.separator +
                            fileDirName + File.separator +
                            shiroName + File.separator;
                }
                return inputPagePath;
            case FreemarketConfigUtil.PAGE_SELECT:
                String treeSelectPagePath = "";
                if (StringUtil.isNotBlank(shiroName)){
                    treeSelectPagePath = FileUtil.getPagePath() +
                            "WEB-INF" + File.separator +
                            "jsp" + File.separator +
                            "module" + File.separator +
                            moudleName + File.separator +
                            fileDirName + File.separator +
                            shiroName + File.separator;
                }else{
                    treeSelectPagePath = FileUtil.getPagePath() +
                            "WEB-INF" + File.separator +
                            "jsp" + File.separator +
                            "module" + File.separator +
                            moudleName + File.separator +
                            fileDirName + File.separator +
                            shiroName + File.separator;
                }
                return treeSelectPagePath;
            default:
                return null;
        }
    }

    /**
     * 获取文件名称
     *
     * @param type 模板类型
     * @return
     * @throws IOException
     */
    private static String getFileName(int type,String className) throws IOException {
        switch (type) {
            case FreemarketConfigUtil.TYPE_MAPPER:
                return StringUtil.upperCaseFirst(className) + "Mapper.xml";
            case FreemarketConfigUtil.TYPE_MODEL:
                return StringUtil.upperCaseFirst(className) + ".java";
            case FreemarketConfigUtil.TYPE_DAO:
                return StringUtil.upperCaseFirst(className) + "Dao.java";
            case FreemarketConfigUtil.TYPE_SERVICE:
                return StringUtil.upperCaseFirst(className) + "Service.java";
            case FreemarketConfigUtil.TYPE_ACTION:
                return StringUtil.upperCaseFirst(className) + "Action.java";
            case FreemarketConfigUtil.PAGE_LIST:
                return className + "-list.jsp";
            case FreemarketConfigUtil.PAGE_INPUT:
                return className + "-input.jsp";
            case FreemarketConfigUtil.PAGE_SELECT:
                return  className + "-select.jsp";
            default:
                return null;
        }
    }

    private static String getBasicProjectPath() {
        String path = new File(FileUtil.class.getClassLoader().getResource("").getFile()).getPath() + File.separator;
        StringBuilder sb = new StringBuilder();
        sb.append(path.substring(0, path.indexOf("target"))).append("src").append(File.separator).append("main").append(File.separator);
        return sb.toString();
    }

    /**
     * 获取源码路径
     *
     * @return
     */
    public static String getSourcePath() {
        StringBuilder sb = new StringBuilder();
        sb.append(getBasicProjectPath()).append("java").append(File.separator);
        return sb.toString();
    }

    /**
     * 获取源码路径
     *
     * @return
     */
    public static String getPagePath() {
        StringBuilder sb = new StringBuilder();
        sb.append(getBasicProjectPath()).append("webapp").append(File.separator);
        return sb.toString();
    }

    /**
     * 获取资源文件路径
     *
     * @return
     */
    public static String getResourcePath() {
        StringBuilder sb = new StringBuilder();
        sb.append(getBasicProjectPath()).append("resources").append(File.separator);
        return sb.toString();
    }

    public static void deleteToJava(GeneratorConfigure configure, GeneratorTable table) throws IOException {
        for(int i = 1 ;i <= 9;i++){
            String path = getFilePath(i, configure.getPackageName(),configure.getProjectName(), table.getMoudleName(), table.getFileDirName(),table.getShiro()) +
                    getFileName(i, table.getClassName());
            // 已存在的文件进行删除
            File file = new File(path);
            if (file.exists()) {
                file.delete();
            }
        }
    }
}
